\documentclass[11pt,a4paper,serbianc,oneside]{book}
\usepackage[utf8x]{inputenc}
\usepackage[T2A]{fontenc}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{textcomp}
\usepackage{amsfonts}
\usepackage{graphicx}
\usepackage{ucs}
\usepackage{listings}
\usepackage[serbianc]{babel}
\usepackage{pdfsync}
\usepackage[left=2.5cm,right=2.5cm,top=2.5cm,bottom=2.5cm]{geometry}
\usepackage[ruled,noline,algochapter]{algorithm2e}



% Komanda za horizontal ruler
\newcommand{\HRule}{\rule{\linewidth}{0.5mm}}

%
% Definicija fiksiranih reci
%
\addto\captionsserbian{%
 \def\prefacename{Предговор}%
 \def\refname{Списак литературе}%
 \def\abstractname{Сажетак}%
 \def\bibname{Литература}%
 \def\chaptername{Глава}%
 \def\appendixname{Додатак}%
 \def\contentsname{Садржај}%
 \def\listfigurename{Списак слика}%
 \def\listtablename{Списак табела}%
 \def\indexname{Регистар}%
 \def\figurename{Слика}%
 \def\tablename{Табела}%
 \def\partname{Део}%
 \def\enclname{Прилози}%
 \def\ccname{Копије}%
 \def\headtoname{Прима}%
 \def\pagename{Страна}%
 \def\seename{Види}%
 \def\alsoname{Види такође}%
 \def\proofname{Доказ}%
 \def\glossaryname{Речник непознатих речи}
 \def\contentsname{Садржај}%
 }%

%
% Podesavanja paketa za listinge
%

\renewcommand{\algorithmcfname}{Алгоритам}


\renewcommand\lstlistingname{Листинг}
\lstset {
	basicstyle=\footnotesize\ttfamily,
	numbers=left,
	numberstyle=\tiny,
	%stepnumber=2,
	numbersep=5pt,
	tabsize=2,
	extendedchars=true,
	breaklines=true,
	keywordstyle=\color{blue},
	frame=b,
	stringstyle=\color{gray}\ttfamily,
	showspaces=false,
	showtabs=false,
	xleftmargin=17pt,
	framexleftmargin=14pt,
	framexrightmargin=3pt,
	framexbottommargin=4pt,
	framextopmargin=0pt,
	%backgroundcolor=\color{lightgray},
	showstringspaces=false
}

\lstloadlanguages {
	% Check Documentation for further languages ...
	%[Visual]Basic
	%Pascal
	%C
	%C++
	Java,
	XML,
	Bash,
	Python
}

%
% Podesavanje okvira listinga
%
\usepackage{color}
\usepackage{colortbl}
\usepackage{xcolor}
\usepackage{caption}
\usepackage{float}
\floatstyle{plaintop}
\restylefloat{table}
\DeclareCaptionFont{white}{\color{white}}
\DeclareCaptionFormat{listing}{\colorbox[cmyk]{0.43, 0.35, 0.35,0.01}{\parbox{\textwidth}{\hspace{12pt}#1#2#3}}}
\captionsetup[lstlisting]{format=listing,labelfont=white,textfont=white, singlelinecheck=false, margin=0pt, font={bf,footnotesize} }

%
% Pocetak dokumenta
%
\begin{document}

\input{naslovna-pz.tex}


\tableofcontents
\newpage


\chapter*{Апстракт}
Овај рад представља опис дизајна и имплементације софтвера за израчунавање структурне осетљивости и максималног отклона за структурне тополошке дескрипторе. Овај рад се може посматрати као својеврстан наставак Студијског истраживачког рада у којем су дефинисани проблематика и методе за решавање, које овај софтвер имплементира.

У првом поглављу је дат опис технологија које су се користиле за решавање проблема. Друго погавље садржи опис дизајна софтвера. Треће поглавље показује резулате добијене извршавањем софвтера. 

\chapter{Увод}

\section{Коришћене технологије}


За имплементацију решења коришћен је програмски језик \textit{Python}. \textit{Python} је изабран првенствено због \textit{NetworkX} библиотеке за рад са графовима, написане за тај језик \cite{networkx}. \textit{NetworkX} је вероватно најкомплетнија постојећа библиотека за рад са графовима. Употреба ове библиотеке је доста утицала на брзину развоја софтвера.


\section{Улазни подаци}


Као улазне податке за наш проблем смо одабрали класу стабала са истим бројем чворова, $n$.
За генерисање улазних податка је коришћен алат \textit{geng} из \textit{nauty} пакета за рад са графовима \cite{nauty}. Једна од многих фунцкионалности овог алата је генерисање скупа неизоморфних графова по задатим критеријумима. Примера ради, класа стабала са 10 чворова се генерише командом:

\begin{lstlisting}[language=bash, frame=none, numbers = none]
geng -cbf 10 9
\end{lstlisting}
чиме смо скуп графова ограничили на повезане(\textit{c}), бипартитне (\textit{b}), ацикличне (\textit{f}) графове са 10 чворова и 9 грана. 

Графови генерисани \textit{geng} алатом налазе се у \textit{graph6} формату. Граф се представља у овом формату на следећи начин \cite{nauty}: 
\begin{enumerate}
\item Горњи троугао матрице суседства се запише као бит вектор дужине $n(n-1)/2$, тако што се редом додају вредности матрице:
 $[0,0]$, $[0,1]$, $[0,2]$,..., $[0,n]$, $[1,1]$, $[1,2]$, $[1,n]$,..., $[n-1,n]$. Претпоставимо да је тај бит вектор записан у облику 100010110001110.
\item Додајемо нуле на крај, тако да укупан број битова буде дељив са шест. У нашем примеру додајемо три нуле и сада имамо бит вектор 100010110001110000. 
\item Бит вектор делимо у групе по 6 битова. Добијамо 100010 110001 110000.
\item Сваки скуп битова претварамо у декадни систем и додајемо вредност 63. Добијамо 97 112 111. 
\item Испред ових вредности додајемо број вредност која одговара броју чворова графа увећану за 63. Добијамо 69 97 112 111.
\item Сваки од ових бројева представимо одговарајућим карактером из \textit{ASCII} кода. Добијамо вредност \textit{Еаpo}.
\end{enumerate}

Примећујемо да овако сачуван граф заузима $1+ceil((n(n-1)/2)/6)$ битова. Фајл који садржи улазне податке дакле садржи низ стрингова који предстљављају графове у \textit{graph6} формату.



\chapter{Објектно-оријентисани дизајн и анализа}

\section{Увод}
Слика \ref{fig:UML} садржи \textit{UML} дијаграм класа коришћених при имплементацији програма. 

\begin{figure}[htp]
\begin{center}
\leavevmode
\includegraphics[width=150mm]{images/ClassDiagPZ.png}
\end{center}
\caption{UML дијаграм}
\label{fig:UML}
\end{figure}


\section{\textit{GraphGroup}}
На Слици \ref{fig:UML} се уочава апстрактна класа \textit{GraphGroup}, која има две подкласе: \textit{GraphGroupDraw} и \textit{GraphGroupMath}. Овакав дизајн је у складу са принципoм једне одговорности(\textit{SRP - Single Responsibillity Principle}) у објектно-оријентисаном моделу, који каже да класа треба да има само једну функционалност \cite{unclebob}. На овај начин се минимизује потреба за честом изменом класа што зна да буде велики проблем у софтверском инжењерству.

Класа \textit{GraphGroup} садржи два атрибута: листу графова и хеш табелу вредности испитиваних тополошких индекса за сваки од графова. Клaса такође садржи методе за додавање графова и рачунања вредности за један тополошки индекс. Листинг \ref{lst:GG} приказује имплементацију класе.

\begin{lstlisting}[language=Python,caption=GraphGroup.py, label = lst:GG]
class GraphGroup:
    
    def __init__(self):
        self.graphs = []
        self.Tis=dict()
        
    def addGraph(self, graph):
        self.graphs.append(graph)
        
    def count(self):
        return len(self.graphs)
    
    def calculateTi(self, topologicalIndex):
        name = topologicalIndex.name()
        values=[] 
        for graph in  self.graphs:
            Ti = topologicalIndex.value(graph)
            values.append(Ti)        
        self.Tis[name]=values   
        return self.Tis 
\end{lstlisting}


У ранијим фазама истраживања јавила се потреба за генерисањем разноразних дијаграма над групом графова како би се олакшала анализа података. У ту сврху је направљена класа  \textit{GraphGroupDraw}.

\begin{lstlisting}[language=Python,caption=GraphGroupDraw.py, label=lst:GGD]
class GraphGroupDraw(GraphGroup):
    
    def drawGraphs(self, directory):
        if not path.exists(directory):
            mkdir(directory)
        index=0
        for graph in self.graphs:
            draw_spring(graph)
            plt.savefig("%s/%snew.png"%(directory, str(index)))
            index += 1 
            plt.clf()            
            
    def drawTiHistogram(self, directory, topologicalIndex):
        if not path.exists(directory):
            mkdir(directory)
        indexName = topologicalIndex.name()
        vector = robjects.FloatVector(self.Tis[indexName]) 
        imageName = "%s/%s.png" % (directory, indexName)
        robjects.r.png(imageName, width = 400 , height = 300)
        robjects.r.hist(vector, main = indexName,xlab="", col="lightblue")
        robjects.r('dev.off()')
        
 \end{lstlisting}
 
Kласа  \textit{GraphGroupDraw}. садржи методе за цртање свих графова у групи коришћењем методa из \textit{NetworkX} библиотеке. Такође, коришћењем R метода могуће је цртати хистограм за вредности тополошких индекса. Листинг \ref{lst:GGD} приказује имплементацију класе.

 

Класа \textit{GraphGroupMath} садржи методе за математичке прорачуне над групом графова. Тренутно су имплементиране статистичке методе за рачунање стандардне девијације и квартила за вредности тополошких индекса, као и метода за рачунање релативне разлике вредности тополошких индекса у односу на тополошки индекс тог графа. Ова класа се ослања на функционалности \textit{R} програмског језика што је могуће у \textit{Python}-у. Листинг \ref{lst:GGM} приказује имплемнтацију класе.
 

\begin{lstlisting}[language=Python,caption=GraphGroupMath.py, label = lst:GGM]
class GraphGroupDraw(GraphGroup):
    
    def drawGraphs(self, directory):
        if not path.exists(directory):
            mkdir(directory)
        index=0
        for graph in self.graphs:
            draw_spring(graph)
            plt.savefig("%s/%snew.png"%(directory, str(index)))
            index += 1 
            plt.clf() 
                       
    def drawTiHistogram(self, directory, topologicalIndex):
        if not path.exists(directory):
            mkdir(directory)
        indexName = topologicalIndex.name()
        vector = robjects.FloatVector(self.Tis[indexName]) 
        imageName = "%s/%s.png" % (directory, indexName)
        robjects.r.png(imageName, width = 400 , height = 300)
        robjects.r.hist(vector, main = indexName,xlab="", col="lightblue")
        robjects.r('dev.off()')
               
\end{lstlisting}
 



\section{\textit{TopologicalIndex}}

Класа \textit{TopologicalIndex} служи за представљање тополошког индекса. Познато је да тополошки индекс рачунамо на следећи начин:

\begin{equation}
TI(G) = \sum_{(u,v) \in E(G)} F(d_u, d_v)
\nonumber
\end{equation}

Дакле, сваки индекс има специфичну функцију над степенма чворова. Овде је искоришћена функионалност \textit{Python}-а која омогућава да се фунцкија може доделити као вредност некој варијабли или атрибуту класе. 

\begin{lstlisting}[language=Python,caption=TopologicalIndex.py, label = lst:TI]
class TopologicalIndex:
    
    def __init__(self, function):
        self.function = function
        
    def value(self, graph):
        s = 0
        for edge in graph.edges():
            du = len(graph.neighbors(edge[0]))
            dv = len(graph.neighbors(edge[1]))
            s += self.function(float64(du), float64(dv))
        return s
    
    def name(self):
        return self.function.__name__
 \end{lstlisting}

Класа \textit{TopologicalIndex} дакле може да рачуна вредност индекса тако што пронађе суму вредности додељене фунцкије над степенима свих парова суседних чворова у графу. Листинг \ref{lst:TI} приказује имплементацију класе. 


\begin{lstlisting}[language=Python,caption=indexFunctions.py, label=lst:IF]
def R(du, dv): return 1 / (sqrt(du * dv))
def M1(du, dv): return du + dv
def M2(du, dv): return du * dv
def ABC(du, dv): return sqrt((du + dv - 2) / (du * dv))
def SCI(du, dv): return 1 / (sqrt(du + dv))
def GA1(du, dv): return 2 * sqrt(du * dv) / (du + dv)
def AZI(du, dv): return  power((du * dv) / (du + dv - 2), 3) 
def HI(du, dv): return 2 / (du + dv)
\end{lstlisting}
 
Све функције индекса које су у током истраживања биле испитивани се налазе у посебном фајлу. За испитивање новог тополошког индекса је потребно само дефинисанити нову фунцкију. Листинг \ref{lst:IF} показује садржај тог фајла.

\section{\textit{GED1GroupGenerator}}


Уколико погледамо \textit{UML} дијаграм класе \textit{GED1GroupGenerator} видимо да се неке фунцкионалности делегирају интерфејсу за генерисање јединственог идентификатора графа. Оно што је битно уочити је да је класа дизајнирана у складу са пројектним обрасцем по имену \textit{Strategy} \cite{unclebob}. На овај начин класа постаје независна од имплементације интерфејса тако да може да ради са више типова генератора јединственог идентификатора, што је добро у случају евентуалног проширивања истраживања на друге типове графова. 

При дизајну класе, коришћен је и такозвани \textit{dependency injection} принцип. Тиме је класа ослобођена од било каквог управљања класом за генерисање јединственог идентификатора. Идеја је да се класи \textit{GED1GroupGenerator} једноставно проследи референца на инстанцу генератора, док ће неки контејенр водити рачуна о самом генератору. 

Листинг \ref{lst:GED1}  садржи део имплементације класе за генерисање групе графова која је структурно најсличнија неком графу. Треба уочити на који начин је имплементиран процес генерисања групе графова. Класа као атрибут има референцу на другу класу за генерисање тополошког обележја графа. У конструктору класе се прослеђује референца на инстанцу класе за генерисање тополошког обележја. Имплементација те класе је непозната, тако да то може да буде класа за генерисање тополошког обележја стабла или било које друге врсте графа.


\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.py, label=lst:GED1]
class GED1GroupGenerator:
    
    def __init__(self, thumbprintGenerator):
        self.thumbprintGenerator = thumbprintGenerator
        
    def setCodeGenerator(self, thumbprintGenerator):
        self.thumbprintGenerator = thumbprintGenerator
\end{lstlisting}

Класа има један метод за генерисање групе графова. Ова метода, премештањем грана стабла конструише све графове који су потенцијални чланови групе. Тополошка обележја чланова групе се чувају у хеш мапи. За сваки од конструисаних графова се проверава да ли је његово обележје у хеш мапи и уколико није, граф се додаје у групу. Листинг \ref{lst:GED1Gr} приказује имплементацију ове методе.


\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.generateGED1Group, label=lst:GED1Gr]       
    def generateGED1Group(self, graph):
        group = []   
        addedGraphs=dict()
        initialThumbprint=self.thumbprintGenerator.generateThumbprint(graph)
        for node in graph.nodes():  
            for neighobor in graph.neighbors(node):
                for nonNeighbor in non_neighbors(graph, node):
                    newGraph = graph.copy()
                    newGraph.remove_edge(node, neighobor)
                    newGraph.add_edge(node, nonNeighbor)            
                    if is_connected(newGraph):
                        thumbprint = self.thumbprintGenerator.generateThumbprint(newGraph)
                        if (thumbprint != initialThumbprint) and (thumbprint not in addedGraphs):
                            addedGraphs[thumbprint] = len(group)
                            group.append(newGraph)       
        return group 
\end{lstlisting}

За наш проблем је имплементирана класа за генерисање тополошких обележја некоренских стабала. У даљем истраживању се може нпр. направити класа за генерисање тополошких обележја других врста графова.

Листинг \ref{lst:thumb} приказује имплементацију метода за генерисање тополошког обележја стабла. Прво се одреде корени стабала. У неким ситуацијама код стабала са парним бројем чворова, као што је објашњено, не можемо јединиствено одредити чвор који би представљао корен стабла. За један или два чвора које пронађемо као корен, врши се тополошко обележавање, и као резултат се враћа лексикографски мање тополошко обележје.
\newpage

\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.generateThumbprint, label = lst:thumb]
    def generateThumbprint(self,graph):
        roots = self.findRoots(graph)
        codes=[]
        for root in roots:
            tree=bfs_tree(graph,root)
            code=self.treeCode(tree, root)
            codes.append(code)
        codes=sorted(codes)
        return codes[0]
 \end{lstlisting}


Листинг \ref{lst:weigh} показује имплементацију методе за мерење тежине стабла, тј. бројање чворовова у подстаблима стабла. Овај метод је потребан за имплементацију алгоритма за избор корена стабла. 

\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.weighNodes, label= lst:weigh]
	def weighNodes(self, tree, node, parent):     
        total = 1 
        children = [neighbor for neighbor in tree.neighbors(node) if neighbor != parent]
        for neighbor in children:
                    total += self.weighNodes(tree, neighbor, node)
        tree.node[node]["weight"] = total
        return total    

\end{lstlisting}

Листинг \ref{lst:shift} приказује имплементацију алгоритма за избор корена. 

\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.shift, label= lst:shift]    
    def shift(self,graph, currentNodeId):
        neighbors  = graph.neighbors(currentNodeId)
        for neighborId in neighbors:     
            if graph.node[neighborId]["weight"] > (graph.number_of_nodes() / 2.0):
                graph.node[currentNodeId]["weight"] -= graph.node[neighborId]["weight"]
                graph.node[neighborId]["weight"] += graph.node[currentNodeId]["weight"]
                return self.shift(graph, neighborId)
            elif graph.node[neighborId]["weight"] == (graph.number_of_nodes() / 2.0):
                return [currentNodeId, neighborId]
        return [currentNodeId]
\end{lstlisting}

Листинг \ref{lst:root} показује метод за избор чвора коренског стабла, тако што се, уколико не постоји јединствени чвор са максималним бројем чворова, позива имплементација алгоритма за трансформација некоренског стабла у коренско.

\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.findRoots, label= lst:root]        
    def findRoots(self,graph):        
        degrees = graph.degree().values()
        maximum=max(degrees)
        count=degrees.count(maximum)
        if count == 1:
            return [degrees.index(maximum)]
        else:
            self.weighNodes(graph, 0, -1)
            return self.shift(graph, 0)

\end{lstlisting}





Листинг \ref{lst:treeCode} садржи имплементацију алгоритма  за генерисање тополошког обележја коренског стабла. 

\begin{lstlisting}[language=Python,caption=GED1GroupGenerator.treeCode, label=lst:treeCode]
  def treeCode(self,tree, node): 
        neighbors = tree.neighbors(node)
        subtreeLabels=[]
        for neighbor in neighbors:
            subtreeLabels.append(self.treeCode(tree, neighbor))
            
        sortedSubtreeLabels=sorted(subtreeLabels)
        
        if len(neighbors) == 0: 
            return str(len(neighbors))
        else: 
            return str(len(neighbors)) + "," + ",".join(sortedSubtreeLabels)
 \end{lstlisting}


\chapter{Резултати}
\section{Увод}
Извршавањем програма добијени су резултати који нам дају бољи увид у квалитет тополошког индекса са аспекта глаткости. 

У предстојећим табелама представљене су добијене вредности за структурну осетљивост и максимални отклон, као и максималне и минималне вредности тополошког индекса у испитиваној класи стабала. На дијаграмима који су приказани показан је процентуални однос структурне осетљивости и максималног отклона у односу на опсег вредности тополошког индекса (разлика максималне и минималне вредности индекса). 

Разлог приказивања процентуалног односа  структурне осетљивости и максималног отклона је тај што на таj начин можемо упоређивати различите индексе на истој скали. Наиме, структурна осетљивост и максимални отклон су апсолутне величине, које за различите индексе имају доста различите вредности, тако да је немогуће упоредити њихове апсолутне величине.


Приказани су резултати за стабла са 6, 10 и 14 чворова. Посматрајући резултате на дијаграмима, уочавамо да су они мање-више неконзизстенти. Можемо закључити да је за бољи увид у квалитет глаткости тополошких индекса потребно обрадити веће калсе стабала. Због овога је потребна паралелизација горе описаног софтвера.
 



\newpage
\section{Резултати за стабла са 6 чворова}
\begin{table}[H]
\centering
\caption{Резултати за стабла са 6 чворова}
\begin{tabular}{l r r r r r r r}
\textit{TI}& \textit{AVG\_SS}& \textit{AVG\_ABBR}& \textit{MIN\_TI}& \textit{MAX\_TI}&\textit{RANGE}&\textit{SS} &\textit{ABBR}  \\
\hline
\textit{ABC}&0.2144&0.3419&3.5355&4.4721&0.9366&22.90\%&36.51\%\\
\textit{AZI}&7.2752&11.3232&9.7656&40.0000&30.2344&24.06\%&37.45\%\\
\textit{GA1}&0.2495&0.3984&3.7268&4.8856&1.1588&21.53\%&34.38\%\\
\textit{HI}&0.2574&0.4056&1.6667&2.8333&1.1667&22.06\%&34.76\%\\
\textit{M1}&3.0586&4.0000&18.0000&30.0000&12.0000&25.49\%&33.33\%\\
\textit{M2}&2.2568&3.3333&16.0000&25.0000&9.0000&25.08\%&37.04\%\\
\textit{R}&0.1472&0.2359&2.2361&2.9142&0.6781&21.70\%&34.79\%\\
\textit{SCI}&0.1324&0.2104&2.0412&2.6547&0.6135&21.58\%&34.29\%\\
\end{tabular}
\end{table}


\vspace{20mm}

\begin{figure}[htb]
\begin{center}
\leavevmode
\includegraphics[width = 150mm, height=105mm]{images/res6.png}
\end{center}
\caption{Структурна осетљивост и максимални отклон за стабла са 6 чворова}
\end{figure}




\newpage
\section{Резултати за стабла са 10 чворова}

\begin{table}[H]
\centering
\caption{Резултати за стабла са 10 чворова}
\begin{tabular}{l r r r r r r r}
\textit{TI}& \textit{AVG\_SS}& \textit{AVG\_ABBR}& \textit{MIN\_TI}& \textit{MAX\_TI}&\textit{RANGE}&\textit{SS}&\textit{ABBR} \\ 
\hline
\textit{ABC}&0.1861&0.3808&6.3235&8.4853&2.1618&8.61\%&17.62\%\\
\textit{AZI}&6.0732&12.6171&12.8145&75.3906&62.5762&9.71\%&20.16\%\\
\textit{GA1}&0.2536&0.4797&5.4000&8.8856&3.4856&7.27\%&13.76\%\\
\textit{HI}&0.2442&0.4580&1.8000&4.8333&3.0333&8.05\%&15.10\%\\
\textit{M1}&3.4278&6.0566&34.0000&90.0000&56.0000&6.12\%&10.82\%\\
\textit{M2}&4.5617&9.8962&32.0000&81.0000&49.0000&9.31\%&20.20\%\\
\textit{R}&0.1434&0.2733&3.0000&4.9142&1.9142&7.49\%&14.28\%\\
\textit{SCI}&0.1352&0.2494&2.8461&4.6547&1.8087&7.48\%&13.79\%\\
\end{tabular}
\end{table}



\vspace{20mm}

\begin{figure}[htb]
\begin{center}
\leavevmode
\includegraphics[width = 150mm, height=105mm]{images/res10.png}
\end{center}
\caption{Структурна осетљивост и максимални отклон за стабла са 10 чворова}
\end{figure}


\newpage
\section{Резултати за стабла са 14 чворова}

\begin{table}[H]
\centering
\caption{Резултати за стабла са 14 чворова}
\begin{tabular}{l r r r r r r r}
\textit{TI}& \textit{AVG\_SS}& \textit{AVG\_ABBR}& \textit{MIN\_TI}& \textit{MAX\_TI}&\textit{RANGE}&\textit{SS}&\textit{ABBR} \\ 
\hline
\textit{ABC}&0.1682&0.4007&9.0977&12.4900&3.3923&4.96\%&11.81\% \\
\textit{AZI}&6.1939&15.2098&16.5284&114.9630&98.4346&6.29\%&15.45\% \\
\textit{GA1}&0.2363&0.5163&6.6960&12.8856&6.1896&3.82\%&8.34\% \\
\textit{HI}&0.2250&0.4814&1.8571&6.8333&4.9762&4.52\%&9.67\% \\ 
\textit{M1}&3.4620&6.9687&50.0000&182.0000&132.0000&2.62\%&5.28\% \\
\textit{M2}&5.6087&14.4587&48.0000&169.0000&121.0000&4.64\%&11.95\% \\
\textit{R}&0.1320&0.2908&3.6056&6.9142&3.3087&3.99\%&8.79\% \\ 
\textit{SCI}&0.1267&0.2663&3.4744&6.6547&3.1803&3.98\%&8.37\% \\
\end{tabular}
\end{table}



\vspace{20mm}

\begin{figure}[htb]
\begin{center}
\leavevmode
\includegraphics[width = 150mm, height=105mm]{images/res14.png}
\end{center}
\caption{Структурна осетљивост и максимални отклон за стабла са 14 чворова}
\end{figure}

\newpage


\chapter*{Закључак}

Циљ овог рада је био опис дизајна и имплементације софтвера за израчунавање структурне осетљивости и максималног отклона за структурне тополошке дескрипторе.

Показане су предности доброг објектно-оријентисаног дизајна софтвера. Анализом резултата се увиђа потреба за испитивањем већих класа стабала а самим тим и потреба за паралелизацијом софтвера. 
 



\begin{thebibliography}{10}

\bibitem{nauty} {Nauty and Traces User's Guide, http://cs.anu.edu.au/people/bdm/nauty/nug.pdf, 2013}
\bibitem{networkx} {NetworkX Reference, http://networkx.github.io/documentation/development/\_downloads/ networkx\_reference.pdf, 2013}
\bibitem{unclebob} {Robert Martin, Agile Software Development, Principles, Patterns, and Practices , Prentice Hall, 2002}




\end{thebibliography}
	
\end{document}


